package com.ucar.umock.client.aspect;

import com.ucar.umock.client.UMockHelper;
import com.ucar.umock.client.config.UMockMethodConfigBean;
import com.ucar.umock.client.dto.UMockMethodRuntimeInfoDTO;
import com.ucar.umock.client.exector.UMockValueExectorComposite;
import com.ucar.umock.client.util.UMockTypeUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @ClassName UMockAspect
 * @Description TODO
 * @Author zhanbs baoshan.zhan@ucarinc.com
 * @Date 2020/4/2 14:19
 * @Version 1.0
 **/
@Component
@Aspect
@Slf4j
public class UMockMethodAspect {
    @Autowired
    private UMockValueExectorComposite umockValueExectorComposite;

    @Around("@annotation(com.ucar.umock.client.annotation.UMock)")
    public Object mockAround(ProceedingJoinPoint point) throws Throwable {
        //测试环境才需要进行Mock 处理
        //获取方法
        MethodSignature methodSignature=(MethodSignature)point.getSignature();
        Method method=methodSignature.getMethod();
        Class returnClass=methodSignature.getReturnType();
        String key= UMockHelper.getMockMethodConfigKey(method);
        UMockMethodConfigBean config= UMockHelper.getMockMethodConfigOperate().getMockMethodConfig(key);
        if(config.isMockSwitch()){
            log.info("[UMock],Class:{}[{}],方法:{}[{}],开启Mock",config.getClassMockName(),config.getClassName(),config.getMethodMockName(),config.getMethodName());
            //空值直接返回
            if(UMockTypeUtil.isVoid(returnClass)){
                return null;
            }else{
                UMockMethodRuntimeInfoDTO methodRuntimeDTO=UMockMethodRuntimeInfoDTO.builder()
                        .methodName(method.getName())
                        .args(point.getArgs())
                        .parameterNames(methodSignature.getParameterNames())
                        .parameterTypes(methodSignature.getParameterTypes())
                        .returnClass(returnClass)
                        .build();
                Object obj=umockValueExectorComposite.exec(config,methodRuntimeDTO);
                return obj;
            }
        }
        return point.proceed();
    }



}
